package com.example.util;

import cn.afterturn.easypoi.word.WordExportUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.util.*;

public class FtlWordUtil {

    private static String path = "C:\\Users\\Administrator\\Desktop\\";

    public static void main(String[] args) {
        String templateName = "mytest";
        String fileName = "123123";
        try {
            Map<String, Object> map = new HashMap<>(4);
            File file = new File("D:\\students - 副本.xls");
            FileInputStream fileInputStream = null;
            try {
                fileInputStream = new FileInputStream(file);
                byte[] bytes = new byte[fileInputStream.available()];
                fileInputStream.read(bytes); // 读取到 byte 里面
                fileInputStream.close();
                BASE64Encoder base64Encoder = new BASE64Encoder();
                // 得到文件 之后转成beye 然后使用base64转码
                String encode = base64Encoder.encode(bytes);// 转码
                map.put("file", encode);
            } catch (Exception e) {
                e.printStackTrace();
            }
            createWord(map,templateName,fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 把文件存储到本地
     * @param name
     * @return
     */
    private static boolean readFileToLoacl(String name) {
        try {
            File pathFile = new File(path);
            //文件夹，不存在，创建文件夹爱
            if(!pathFile.exists()){
                pathFile.mkdirs();
            }
            File file = new File(path + name);
            if (!file.exists()) {
                ClassPathResource classPathResource = new ClassPathResource("templates/ftl/" + name);
                InputStream inputStream = classPathResource.getInputStream();
                writeToLocal(path + name, inputStream);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("ftl file to local err");
        }
        return false;
    }

    /**
     * 将InputStream写入本地文件
     *
     * @param path  写入本地目录
     * @param input 输入流
     * @throws IOException IOException
     */
    public static void writeToLocal(String path, InputStream input)
            throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(path);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        input.close();
        downloadFile.close();

    }

    public static void createWord(Map<String, Object> dataMap, String templateName,
                                  String fileName) throws Exception {
        templateName = templateName + ".ftl";
        boolean bool = readFileToLoacl(templateName);
        if (bool) {
            Configuration cfg = new Configuration();
            cfg.setDefaultEncoding("UTF-8");
            //模板文件所在路径
            cfg.setClassForTemplateLoading(FtlWordUtil.class, "/");
            cfg.setDirectoryForTemplateLoading(new File(path));
            //获取模板文件
            Template t = cfg.getTemplate(templateName);
            //导出文件
            File outFile = new File(path + fileName + ".doc");
            // 需要给 OutputStreamWriter 增加编码，不加可能会导致文件损坏
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8");
            Writer out = new BufferedWriter(outputStreamWriter);
            //将填充数据填入模板文件并输出到目标文件
            t.process(dataMap, out);
            out.close();
        } else {

            throw new Exception("文件缓存本地失败");
        }
    }

    public static ByteArrayOutputStream readFileWord(String fileName) {
        FileInputStream fin = null;
        ByteArrayOutputStream bout = null;
        byte[] arr = null;
        try {
            fin = new FileInputStream(path + fileName + ".doc");
            bout = new ByteArrayOutputStream();
            int len;
            while ((len = fin.read()) != -1) {
                bout.write(len);
            }
            arr = bout.toByteArray();
            String comment = new String(arr);
            System.out.println(comment);
            System.out.println("========================");
            System.out.println(bout);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fin.close();
                bout.close();
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("");
            }
        }
        return bout;
    }

    public static void deleteFile(String fileName) {
        File file = new File(path + fileName + ".doc");
        if (file.exists()) {
            boolean bool = file.getAbsoluteFile().delete();
            if (bool) {
                System.out.println("删除成功");
            } else {
                System.out.println("删除失败");
            }
        }
    }

    public static Map<String, Object> getDbdTest() {
        Map<String, Object> map = new HashMap<>();
        map.put("YJGDLSH", "YJGDLSH工单流水号");
        map.put("YJDBFSBMDW", "YJDBFSBMDW测试");
        map.put("YJDBXFR", "YJDBXFR测试");
        map.put("XFRLXFS", "XFRLXFS测试");
        map.put("FBSJ", "FBSJ测试");
        map.put("YQWCSJ", "YQWCSJ测试");
        map.put("YJJSDW", "YJJSDW测试");
        map.put("YJJSRY", "YJJSRY测试");
        map.put("JSRLXFS", "JSRLXFS测试");
        map.put("CKSJ", "CKSJ测试");
        map.put("CLJGFKSJ", "CLJGFKSJ测试");
        map.put("YJMC", "YJMC测试");
        map.put("YJNR", "YJNR测试");
        map.put("BZ", "BZ测试");
        map.put("FKNR", "JJDBJJBMDW测试");
        List<Map<String,Object>> list = new ArrayList<>();
        for(int i=0;i<10;i++){
            Map<String,Object> m = new HashMap<>();
            m.put("name","纪卫东测试nane"+i);
            m.put("yj","纪卫东测试yj"+i);
            list.add(m);
        }
        map.put("list",list);
        return map;
    }

    public static Map<String, Object> getYJDTest() {
        Map<String, Object> map = new HashMap<>();
        map.put("YJGDLSH", "YJGDLSH测试");
        map.put("YJDBFSBMDW", "YJDBFSBMDW测试");
        map.put("YJDBXFR", "YJDBXFR测试");
        map.put("XFRLXFS", "XFRLXFS测试");
        map.put("FBSJ", "FBSJ测试");
        map.put("YQWCSJ", "YQWCSJ测试");
        map.put("YJJSDW", "YJJSDW测试");
        map.put("YJJSRY", "YJJSRY测试");
        map.put("JSRLXFS", "JSRLXFS测试");
        map.put("CKSJ", "CKSJ测试");
        map.put("CLJGFKSJ", "CLJGFKSJ测试");
        map.put("YJMC", "YJMC测试");
        map.put("YJNR", "YJNR测试");
        map.put("BZ", "BZ测试");
        map.put("FKNR", "JJDBJJBMDW");
        map.put("CJ15", "CJ15");
        map.put("CJ16", "CJ16");
        return nullToEmpty(map);
    }

    public static Map<String, Object> nullToEmpty(Map<String, Object> map) {
        Set<String> set = map.keySet();
        if (set != null && !set.isEmpty()) {
            for (String key : set) {
                if (map.get(key) == null) {
                    map.put(key, "");
                }
            }
        }
        return map;
    }


    /**
     * 导出word
     * <p>第一步生成替换后的word文件，只支持docx</p>
     * <p>第二步下载生成的文件</p>
     * <p>第三步删除生成的临时文件</p>
     * 模版变量中变量格式：{{foo}}
     *
     * @param templatePath word模板地址
     * @param temDir       生成临时文件存放地址
     * @param fileName     文件名
     * @param params       替换的参数
     */
    public static void exportWord(String templatePath, String temDir, String fileName, Map<String, Object> params) {
        Assert.notNull(templatePath, "模板路径不能为空");
        Assert.notNull(temDir, "临时文件路径不能为空");
        Assert.notNull(fileName, "导出文件名不能为空");
        Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");
        if (!temDir.endsWith("/")) {
            temDir = temDir + File.separator;
        }
        File dir = new File(temDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        try {
            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
            String tmpPath = temDir + fileName;
            FileOutputStream fos = new FileOutputStream(tmpPath);
            doc.write(fos);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
